import { _decorator, Component, sys, assetManager, director, error, log, warn, native } from 'cc';

const { ccclass, property } = _decorator;

// 热更新相关配置
interface HotUpdateConfig {
    // 热更新服务器地址
    hotUpdateServerUrl: string;
    // 应用当前版本
    currentVersion: string;
    // 是否在控制台打印详细日志
    debug: boolean;
}

@ccclass('HotUpdateManager')
export class HotUpdateManager extends Component {
    // 单例模式
    private static _instance: HotUpdateManager = null;
    public static getInstance(): HotUpdateManager {
        return this._instance;
    }

    // 热更新配置
    private config: HotUpdateConfig = {
        hotUpdateServerUrl: 'https://your-hot-update-server.com/path/to/hotupdate',
        currentVersion: '1.0.0',
        debug: true
    };

    // 热更新相关变量
    private _am: assetManager.AssetManager = null;
    private _storagePath: string = '';
    private _updating: boolean = false;
    private _packageUrl: string = '';

    protected onLoad(): void {
        if (HotUpdateManager._instance === null) {
            HotUpdateManager._instance = this;
        } else {
            this.destroy();
            return;
        }
        fileUtils.
        // 正确获取存储路径，适配不同平台
        this.initStoragePath();
        
        // 获取默认的资源管理器实例
        this._am = assetManager.assetManager;
        this.log('热更新管理器初始化完成');
    }
    
    /**
     * 初始化热更新存储路径，适配不同平台
     */
    private initStoragePath(): void {
        try {
            // 微信小游戏平台
            if (CC_WECHATGAME && window && window['wx']) {
                // 微信小游戏使用本地缓存目录
                this._storagePath = `${wx.env.USER_DATA_PATH}/hot_update`;
                this.log(`微信小游戏平台，热更新存储路径: ${this._storagePath}`);
            }
            
            // Web平台
            else if (CC_WEB) {
                // Web平台使用localStorage存储，这里使用固定路径
                this._storagePath = '/hot_update';
                this.log(`Web平台，使用localStorage存储`);
            }
            // 原生平台 (iOS/Android)
            else if (CC_JSB && native && native.fileUtil) {
                // 尝试使用sys.localStoragePath
                if (sys.localStoragePath) {
                    this._storagePath = sys.localStoragePath + '/hot_update';
                } else {
                    // 备选方案
                    this._storagePath = native.fileUtil.getWritablePath() + '/hot_update';
                }
                this.log(`原生平台，热更新存储路径: ${this._storagePath}`);
                
                // 确保目录存在
                if (!native.fileUtil.isDirectoryExist(this._storagePath)) {
                    native.fileUtil.createDirectory(this._storagePath);
                }
            }
            // 其他平台的默认处理
            else {
                this._storagePath = '/hot_update';
                this.log(`其他平台，默认热更新存储路径: ${this._storagePath}`);
            }
        } catch (e) {
            this.error(`初始化存储路径失败: ${(e as Error).message}`);
            // 确保有默认路径，防止程序崩溃
            this._storagePath = '/hot_update';
        }
    }

    start() {
        // 可以在这里自动检查更新
        // this.checkUpdate();
    }

    /**
     * 设置热更新配置
     * @param config 热更新配置对象
     */
    public setConfig(config: Partial<HotUpdateConfig>): void {
        this.config = { ...this.config, ...config };
        this._packageUrl = this.config.hotUpdateServerUrl;
    }

    /**
     * 检查是否有更新
     * @param callback 检查结果回调
     */
    public checkUpdate(callback?: (hasUpdate: boolean, manifest: any) => void): void {
        if (this._updating) {
            this.warn('正在更新中，请等待当前更新完成');
            callback?.(false, null);
            return;
        }

        if (!this.config.hotUpdateServerUrl) {
            this.error('热更新服务器地址未配置');
            callback?.(false, null);
            return;
        }

        this._updating = true;
        
        try {
            // 在Web平台上，热更新需要使用Downloader和Parser
            if (CC_WECHATGAME) {
                // 检查是否支持热更新
                if (!native || !native.fileUtil) {
                    this.error('当前环境不支持热更新');
                    this._updating = false;
                    callback?.(false, null);
                    return;
                }
                
                // 检查存储路径是否存在，不存在则创建
                if (!native.fileUtil.isDirectoryExist(this._storagePath)) {
                    native.fileUtil.createDirectory(this._storagePath);
                }
            }
            
            // 构造manifest路径
            const manifestUrl = this.config.hotUpdateServerUrl + '/project.manifest';
            this.log(`开始检查更新，manifest地址: ${manifestUrl}`);
            
            // 在实际项目中，这里应该使用assetManager.loadRemote来加载manifest文件
            // 由于是示例，这里模拟检查更新的结果
            // 实际项目中请替换为真实的manifest加载和解析逻辑
            
            // 模拟网络延迟
            setTimeout(() => {
                this._updating = false;
                // 模拟没有更新的情况，实际项目中应该根据manifest内容判断
                this.log('当前已是最新版本');
                callback?.(false, null);
            }, 1000);
        } catch (e) {
            this.error(`检查更新失败: ${(e as Error).message}`);
            this._updating = false;
            callback?.(false, null);
        }
    }

    /**
     * 下载更新
     * @param callback 更新进度回调
     * @param finishCallback 更新完成回调
     */
    public downloadUpdate(
        callback?: (progress: number) => void,
        finishCallback?: (success: boolean, error?: Error) => void
    ): void {
        if (this._updating) {
            this.warn('正在更新中，请等待当前更新完成');
            finishCallback?.(false, new Error('正在更新中'));
            return;
        }

        if (!this.config.hotUpdateServerUrl) {
            this.error('热更新服务器地址未配置');
            finishCallback?.(false, new Error('热更新服务器地址未配置'));
            return;
        }

        this._updating = true;
        this.log('开始下载更新');
        
        // 模拟下载进度
        let progress = 0;
        const interval = setInterval(() => {
            progress += 0.05;
            if (progress >= 1) {
                progress = 1;
                clearInterval(interval);
                this._updating = false;
                this.log('更新下载完成');
                finishCallback?.(true);
            } else {
                callback?.(progress);
            }
        }, 200);
        
        // 在实际项目中，这里应该使用assetManager的热更新API来下载更新文件
        // 例如：使用assetManager.downloader来下载文件
    }

    /**
     * 应用更新并重启游戏
     */
    public applyUpdateAndRestart(): void {
        this.log('应用更新并重启游戏');
        
        // 清除缓存
        assetManager.clearCache();
        
        // 重新加载当前场景以应用更新
        director.loadScene(director.getScene().name);
    }

    /**
     * 获取热更新存储路径
     */
    public getStoragePath(): string {
        return this._storagePath;
    }

    /**
     * 日志打印
     */
    private log(message: string): void {
        if (this.config.debug) {
            log(`[HotUpdate] ${message}`);
        }
    }

    /**
     * 警告打印
     */
    private warn(message: string): void {
        warn(`[HotUpdate] ${message}`);
    }

    /**
     * 错误打印
     */
    private error(message: string): void {
        error(`[HotUpdate] ${message}`);
    }

    protected onDestroy(): void {
        if (HotUpdateManager._instance === this) {
            HotUpdateManager._instance = null;
        }
    }
}